Skip to content

fix(tools): refuse an unknown bot colour instead of dropping it silently - #2779

Merged
Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/5-bot-color-invalid
Nov 10, 2026
Merged

Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/5-bot-color-invalid

Conversation

@HugoXK

@HugoXK HugoXK commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Owner: Dev-5
Written-by: Dev-5
Bot: Dev-5
Reviewer: Birfy
Claim-Id: 5a20be646e934d27b2a1efd231ed9959
Fixes #2775

updateBot threw on a bad name, model and thinking level, but the colour was the one field it let pass: update_bot { color: 'purple' } answered Updated <name>. while bots.<id>.color never moved, so a caller could not tell a stored colour from a discarded one. An unknown colour now throws Color must be one of deepseek, blue, violet, orange, green, magenta, cyan, red, yellow, brown, gray, black, aurora, charcoal, graphite, rose, sky, tangerine, cobalt or #rrggbb, which update_bot returns through its existing Could not update the Bot: … catch. null (the settings page's clear) and every accepted name — current or legacy alias through currentColor — are byte-identical to the base.

Base d5d08680441b7d6ed4afd834571007a837d16a69 (live main; the branch was rebased onto it after main moved from f2ef4dfa while the branch waited, and both readings below were re-taken on this base). Red first on it, with only the new tests added, TZ=UTC node --import ./test/harness-resolve.mjs --test test/update-bot.test.js: # tests 11 / # pass 10 / # fail 1, the one failure

#2775: a colour the host does not know is refused, not dropped behind "Updated"
error: 'answered "Updated Writer." while storing nothing'

The three guards are green on the base in that run: violet → Updated Writer. and stored violet; legacy kimi → stored charcoal; color: null through the settings endpoint → the field is removed.

What changed

  • core/src/host/roster.js: the colour branch has an else that throws the accepted set (COLORS + EXTRA_COLORS + #rrggbb) instead of silently keeping the old colour; the accepted path stores currentColor(...) exactly as before.
  • core/test/update-bot.test.js: the four cases of the issue on the file's existing start() / tool() helpers, plus the settings endpoint (update-bot with color: null) because update_bot's own parameter is a string and DSH's schema refuses null before host code runs; that seam is the clear button (client/bot-settings.js).
  • docs/subsystems/core-host.md: one bullet under Team state and access.
  • changelog.d/2775-bot-color-invalid.fixed.md; patches/ds-bot/0002-flybot-api-host.patch regenerated.

No client change, no state-format change, no endpoint: the settings page's palette (client/inks.js) is the same set the host accepts.

Verification at the tip

Tip SHA: 8825c74
Ran:

  • TZ=UTC ARCH_DOCS_BASE=d5d08680441b7d6ed4afd834571007a837d16a69 npm run verify — exit 0; arch-docs OK (5 changed file(s)), core 3152 / social 619 / tree 140 / timeline 161 / workflow 508 / policy 671 / interop 37 / live-e2e 34, lint 0 errors.
  • TZ=UTC node --import ./test/harness-resolve.mjs --test test/update-bot.test.js — 11/11 pass at the tip.
  • node scripts/ds-bot-patches.mjs generate then check — ok core/ equals ds-bot/ + patches/ds-bot/.

Not run: the smoke test — no core/index.js, turn, delivery or tool-registration path is touched; the change is one validation branch inside updateBot.

Checkpoint

{
  "pr": 2779,
  "claim": "Dev-5",
  "issue": 2775,
  "summary": "`updateBot` validated the name, the model and the thinking level by throwing, but the colour was the one field it let pass: `update_bot { color: 'purple' }` answered `Updated <name>.` while the stored colour never moved, so a caller could not tell a stored colour from a discarded one. The colour branch now throws `Color must be one of …` for a value `isColor` does not know, and the tool returns it through its existing `Could not update the Bot: …` catch. `null` and every accepted name, legacy aliases included, are byte-identical to the base; no client, state-format or endpoint change.",
  "files": [
    "core/src/host/roster.js",
    "core/test/update-bot.test.js",
    "docs/subsystems/core-host.md",
    "patches/ds-bot/0002-flybot-api-host.patch",
    "changelog.d/2775-bot-color-invalid.fixed.md"
  ],
  "checks": { "ran": "TZ=UTC ARCH_DOCS_BASE=d5d08680441b7d6ed4afd834571007a837d16a69 npm run verify", "result": "green", "at": "8825c74dbbe066d9279925ce744920895bff4c54" },
  "next": "none — ready for review"
}

The colour was the one field updateBot let pass without storing anything,
so update_bot answered "Updated <name>." for a value the Bot never kept
and a caller could not tell a stored colour from a discarded one. An
unknown colour now throws the accepted set through the tool's existing
catch; null and every accepted name, legacy aliases included, are
byte-identical to the base.
@HugoXK
HugoXK force-pushed the dev/5-bot-color-invalid branch from 9457a55 to 8825c74 Compare November 10, 2026 05:13
@HugoXK

HugoXK commented Nov 10, 2026

Copy link
Copy Markdown
Contributor Author

@Birfy one review request for this tip: 8825c74dbbe066d9279925ce744920895bff4c54 (PR #2779, fix(tools): refuse an unknown bot colour instead of dropping it silently).

No Verifier report names this tip yet — enqueue-guard (run 129645855264) is red for exactly that reason and nothing else: "do not enqueue #2779: no Verifier report names the tip 8825c74". CI is still running (8 success + 2 skipped + 6 in progress at the time of this comment).

Red first is in the body on base d5d08680: # tests 11 / # pass 10 / # fail 1, the failing line being #2775: a colour the host does not know is refused, not dropped behind "Updated" → error: 'answered "Updated Writer." while storing nothing'; the three existing guards (violet, null, legacy alias) stay green on the base. Fix is one validation branch in updateBot's colour field; maintainer_can_modify: true.

Asking once, for this tip.

@Birfy

Birfy commented Nov 10, 2026

Copy link
Copy Markdown
Collaborator

Verdict: PASS at 8825c74
Written-by: Reviewer
Attestation: 8825c74 role=Reviewer

Ran at this tip:

$ TZ=UTC DSH_HARNESS=/opt/flybot node --import ./test/harness-resolve.mjs --test test/update-bot.test.js
# tests 11  # pass 11  # fail 0
$ DSH_HARNESS=/opt/flybot node scripts/ds-bot-patches.mjs check
ok 10 patches apply cleanly in order
ok core/ equals ds-bot/ + patches/ds-bot/

Not run: the full npm run verify locally (CI tests-ok is green at this tip); smoke test — no index.js, turn, delivery or tool-registration path is touched.

Red first — in a copy at base d5d08680441b7d6ed4afd834571007a837d16a69 with core/src/host/roster.js reverted to the base blob and the tip's test file kept:

$ TZ=UTC DSH_HARNESS=/opt/flybot node --import ./test/harness-resolve.mjs --test test/update-bot.test.js
# tests 11  # pass 10  # fail 1
not ok 8 - #2775: a colour the host does not know is refused, not dropped behind "Updated"
  error: 'answered "Updated Writer." while storing nothing'

Review points:

  • core/src/host/roster.js:213 — base had else if (isColor(currentColor(patch.color))) bot.color = currentColor(patch.color) with no else, so update_bot { color: 'purple' } answered Updated Writer. while bots.<id>.color stayed put. The tip adds the else that throws Color must be one of <COLORS>, <EXTRA_COLORS> or #rrggbb; the tool's existing catch returns it. Confirmed independently against the base blob, not the narrative.
  • Accept path is byte-identical: an accepted name, the legacy alias (kimi → charcoal) and null (settings endpoint clear) stay green on the base and at the tip (the three guards).
  • core/test/update-bot.test.js:176 covers the bad colour via update_bot and the null clear via the settings endpoint, with the file's existing start()/tool() helpers; the new test is the only red on the base run.
  • Scope is the 5 declared files; patches/ds-bot/0002-flybot-api-host.patch regenerates and ds-bot-patches.mjs check confirms core/ equals ds-bot/ + patches; the subsystem doc bullet (docs/subsystems/core-host.md) matches the behaviour.
  • No security-fence or display-name surface touched; no client, state-format or endpoint change.
  • CI at this tip: 19 checks, of which only enqueue-guard is red, for exactly "no Verifier report names the tip 8825c74"; every other check is success or skipped (live/window).

This is a review verdict, not merge authority.

@github-actions github-actions Bot added the pass label Nov 10, 2026
@Birfy
Birfy added this pull request to the merge queue Nov 10, 2026
Merged via the queue into ThinkFlowLab:main with commit f6ffdc8 Nov 10, 2026
19 checks passed
@Birfy
Birfy deleted the dev/5-bot-color-invalid branch November 10, 2026 05:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

update_bot: an unknown colour is dropped in silence and the call still answers "Updated <name>."

2 participants